
<!DOCTYPE html>
<html lang="zh-cn">
<head>
    <title>NESASM</title>
    <style>
    html,body{font-size:14px; color:#444;} 
    a {text-decoration: none; color:blue;}
    a:hover{color:red;}
    .main{margin:0 auto; width:960px;}
    .box{border:1px solid #eee;}
    </style>
</head>

<body>

<div class="main">
<p>【PPU】
</p><p>NES上发生的一切都需要通过图形方式输出，我们需要对PPU（图像处理单元）编程。其实很简单，就是向特定内存地址写一些数值，然后PPU的设置就被修改为你设置的值。NES所有编程都使用所谓的内存映射寄存器（MMR）实现。如果你给GBA编过程序，肯定知道MMR。但对于Intel芯片知识来说，MMR是个外星人。
</p><p>【二进制注意事项】
</p><p>为了绝对清晰，我们将按以下顺序给出内存寄存器的比特（0x63）：
</p><p>bit： 7  6  5  4  3  2  1  0
</p><p>val：0  1  1  0  0  0  1  1
</p><p>所以，第7比特位于最左边，第0比特位于最右边。
</p><p>【设置PPU】
</p><p>注意首先要做的一件事是设置PPU。我们只需向存储器$2000和$2001写一些值，这两个地址对应两个PPU控制寄存器。为了解释$2000和$2001，下面从YOSHi的文档里面摘抄的寄存器描述：
</p><p>            2000h - PPU 控制寄存器 1 (只写)
</p><p>  Bit7  发生VBlank时执行NMI               (0=Disabled, 1=Enabled)
</p><p>  Bit6  PPU 主从模式选择                  (0=主模式, 1=从模式) (NES中没用)
</p><p>  Bit5  主角尺寸                          (0=8x8, 1=8x16)
</p><p>  Bit4  背景Pattern Table 首地址          (0=VRAM 0000h, 1=VRAM 1000h)
</p><p>  Bit3  主角Pattern Table 首地址          (0=VRAM 0000h, 1=VRAM 1000h)
</p><p>  Bit2  端口0x2007 VRAM 地址增量          (0=自动增1, 1=自动增32)
</p><p>  Bit1-0 Name Table卷轴首地址             (0-3=VRAM 2000h,2400h,2800h,2C00h)
</p><p>  (也就是说，Bit0=水平卷轴滚动256, Bit1=垂直卷轴滚动240)
</p><p>2001h - PPU 控制寄存器 2 (只写)
</p><p>  Bit7-5 颜色增强                         (0=正常, 1-7=增强) 
</p><p>  Bit4  主角可见                          (0=不显示, 1=显示)
</p><p>  Bit3  背景可见                          (0=不显示, 1=显示)
</p><p>  Bit2  主角切除                          (0=切除左边8个像素列, 1=不切除)
</p><p>  Bit1  背景切除                          (0=切除左边8个像素列, 1=不切除)
</p><p>  Bit0  灰度模式                          (0=彩色模式, 1=灰度模式)  
</p><p>为了设置PPU，我们进行两次写内存操作，代码为：
</p><p>    lda #%00001000 
</p><p>    sta $2000
</p><p>    lda #%00011110
</p><p>    sta $2001
</p><p>我们写入$2000的值表示告诉PPU以下内容：
</p><p>NMI禁止了；
</p><p>主角尺寸8x8；
</p><p>背景Pattern Table起始地址$0000；
</p><p>主角Pattern Table起始地址$1000；
</p><p>地址自动增1；
</p><p>NameTable起始地址$2000；
</p><p>写入$2001的值告诉PPU：
</p><p>不要影响调色板；
</p><p>显示主角；
</p><p>显示背景；
</p><p>显示所有位置的主角；
</p><p>显示最左边8像素；
</p><p>彩色模式；
</p><p>你自己应该能从二进制码读懂上述具体含义。
</p><p>【为了获得输出我们还需要做什么？】
</p><p>如果你说的是背景，我们还要做：
</p><p>制作一个背景；
</p><p>a. 绘制一些tile（用Tile Layer Pro）；
</p><p>b. 在段2首先包含上面的tile文件；
</p><p>c. 创建并载入一个调色板；
</p><p>d. 在Name Table中设置显示的tile号码
</p><p>这样就显示了背景！
</p><p>如果是主角，那么顺序应该是这样：
</p><p>制作一个主角：
</p><p>a. 在Tile Layer Pro中绘制主角；
</p><p>b. 段2中包含该文件作为第二个；
</p><p>c. 创建并载入调色板；
</p><p>d. 在主角数据区（类似GBA中的OAM）设置主角属性；
</p><p>主角出场！
</p><p>我们明天学习怎样载入调色板。调色板很重要，一半是背景调色，一半是主角调色。
</p></div>
</body>
</html>
